<!-- 正在执行的同步进度 -->
<template>
  <n-modal
    v-model:show="showRunningModal"
    class=""
    preset="dialog"
    :title="'Running'"
    :bordered="false"
    :segmented="{content: 'soft', footer: 'soft'}"
    :show-icon="false"
    :maskClosable="true"
    :style="{ width: '40em', minHeight: '23em' }"
    >

    <n-spin :show="loading" style="min-height: 60px">
    <n-scrollbar style="max-height:13em" :trigger="'hover'" >
      <template v-if="!tasks || tasks.length==0"> 
        <n-empty description="..." size="small"></n-empty>
      </template>
      <!-- 正在执行： -->
      <div v-for="item,index in tasks" :key="'running_synclog_'+index" 
          class="task">
        <n-progress
            type="line" status="info"
            :percentage="item.progress"
            processing
          >
          <div style="min-width:12em">
            <span class="progress"> {{ item.progress }} %</span>
            <span class="size grey-text"> ({{ item.sizeSendStr }} / {{ item.sizeTotalStr }}) </span>
          </div>
        </n-progress>
        <div v-if="item.log" class="path-wrapper">
          <div class="grey-text path">
            <div><n-ellipsis :line-clamp="1" :title="item.log.sourceBase"> {{ item.log.sourceBase }} </n-ellipsis> </div>
            <div><n-ellipsis :line-clamp="1" :title="item.log.source"> {{ item.log.source }} </n-ellipsis></div>
          </div>
  
          <div class="grey-text path">
            <div><n-ellipsis :line-clamp="1" :title="item.log.targetBase"> {{ item.log.targetBase }} </n-ellipsis></div> 
            <div><n-ellipsis :line-clamp="1" :title="item.log.target"> {{ item.log.target }} </n-ellipsis></div>
          </div>
        </div>
      </div>
    <!--
      <div v-for="item,index in tasks" :key="'running_synclog_'+index" 
          class="task">
        <n-progress
            type="line" status="info"
            :percentage="item.progress"
            processing
            :height="16"
          >
          <div style="min-width:12em">
            {{ item.progress }} %
            <span class="size grey-text"> ({{ item.sizeSendStr }} / {{ item.sizeTotalStr }}) </span>
          </div>
        </n-progress>
        <div v-if="item.log" class="path-wrapper">
          <div class="grey-text path">
            <div> {{ item.log.sourceBase }} </div> 
            <div> {{ item.log.source }} </div>
          </div>
  
          <div class="grey-text path">
            <div> {{ item.log.targetBase }} </div> 
            <div> {{ item.log.target }}  </div>
          </div>
        </div>
      </div>
    -->

    </n-scrollbar>
    </n-spin>
    
    <div class="info-divider"></div>

    <!-- 记录 -->
    <n-scrollbar style="max-height:20em" :trigger="'hover'" >
      <div v-for="item,index in syncLogs" :key="'syncLog_'+index"
        class="log-item path-wrapper">
        <div class="update-time">{{item.updateTime}}</div>
        <div class="grey-text path">
          <div><n-ellipsis :line-clamp="1" :title="item.sourceBase"> {{ item.sourceBase }}</n-ellipsis> </div> 
          <div><n-ellipsis :line-clamp="1" :title="item.source"> {{ item.source }}</n-ellipsis> </div>
        </div>

        <div class="grey-text path">
          <div><n-ellipsis :line-clamp="1" :title="item.targetBase"> {{ item.targetBase }} </n-ellipsis></div> 
          <div><n-ellipsis :line-clamp="1" :title="item.target"> {{ item.target }} </n-ellipsis></div>
        </div>
      </div>
    </n-scrollbar>

  </n-modal>

</template>

<script setup>
import { ref, onUnmounted } from 'vue'
import { NProgress, NEmpty } from 'naive-ui'
import globalStore from '/src/components/pinia/store.js'
import serverApi from '/src/api/fsync/server.js'

const showRunningModal = ref(false)
const loading = ref(true)

// 默认用户 id 为1
let baseHttpHost = import.meta.env.VITE_API_HOST
if ( !baseHttpHost || baseHttpHost=='/') {
  baseHttpHost = window.location.origin
}

const wsurl = baseHttpHost.replace("http", "ws") 
    + "/tasksock/1";
const tasks = ref(null) // { id: {progress, sizeSend, sizeTotal, sizeSendStr, sizeTotalStr, log} }
const syncLogs = ref(null)

const socket = ref(null)
var lastTime = 0
var minDeltaTime = 1000  // 限制最快 一秒一次请求
// 连接 ws
const openws = async () => {
  socket.value = await new WebSocket(wsurl)

  socket.value.onclose = () => {
    console.warn("close")
  }
  socket.value.onerror = (err) => {
    console.error(err)
  }
  socket.value.onmessage = (res) => {
    let data = res.data  // response 的data
    if(!data) {
      return
    }
    data = JSON.parse(data)?.data // 自定义结构中的 data

    // 所有上传队列
    if(data.type == 'tasks') {
      loading.value = false
      tasks.value = data.data

      if(data.data) { // 有数据的时候 1s一次，没有的时候 3s一次
        //console.log("data", data)
        minDeltaTime = 1000
      } else {
        minDeltaTime = 3000
      }

      // requestTasks()
      let currTime =  (new Date()).getTime()
      let deltaTime = currTime - lastTime
      if(deltaTime >= minDeltaTime) {
        requestTasks()
      } else {
        setTimeout(() => {
          requestTasks()
          lastTime = (new Date()).getTime()
        }, minDeltaTime - deltaTime)
      }
    } else if(data.type == 'login') {
      if(data.data) {
        requestTasks()
        lastTime = (new Date()).getTime()
      }
    } else if(data.type == 'finish') {
      let newSyncLog = data.data
      if (newSyncLog) {
        syncLogs.value.unshift(newSyncLog)
      }

    }
  }
  socket.value.onopen = async () => {
    const store = globalStore()
    // 先发送登录
    await sendObj({ type: "login", data: store.token })
    // // 再订阅所有的任务
    // requestTasks()
  } 


  // 获取所有的任务
  const requestTasks = async () => {
    await sendObj({ type: "tasks" })
  }
}

// 发送信息
const sendObj = async (obj) => {
  await socket.value.send(JSON.stringify(obj))
}

// 获取所有记录
const listSyncLogs = () => {
  serverApi.logs({size: 10}).then(res => {
    syncLogs.value = res.data ? res.data : []
  })
}

const show = () => {
  showRunningModal.value =  true
  openws()
  listSyncLogs()
}

// 注销
onUnmounted(() => {
  if(socket.value) {
    socket.value.close()
  }
})

defineExpose({
  show,
})

</script>

<style scoped lang="scss">
.task{
  margin: 0.2em 0em;
}
.grey-text{
  color: gray;
  font-size: 0.8em;
  text-align: right;
}
.progress{
  color: #6868eb;
}
.size{
  color: black;
}

.path-wrapper{
  display: flex;
  align-items: center;
}
.path{
  padding: 0em 0.5em;
  text-align: left;
  flex: 1;

  &>div{
    margin: 0;
    padding: 0;
    line-height: 1.1em;
  }
}

.info-divider{
  height: 1px;
  border-top: 1px dashed #3ea30a;
  margin: 0.5em 0em;
}
.update-time{
  font-size: 0.8em;
  width: 7em;
  flex: none !important;
}
.log-item{
  border-radius: 4px;
  margin: 4px 0px;
  padding: 0em 0.2em;
  border: 1px solid #d7d7d7;
}
</style>
